package net.portly.cst.tools;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.portly.cst.output.OutputFormat;

public class ArgsManager implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Map<String, String> argMap = new HashMap<String, String>();
	private List<String> errors = new ArrayList<String>();
	private OutputFormat outputFormat = null;

	public ArgsManager(String args[]) {
		separateArgs(args);
	}

	public ArgsManager(String location) {
		separateArgsFromPropertiesFile(location);
	}

	private void separateArgsFromPropertiesFile(String location) {
	}

	// * h - host
	// * a - asset types
	// * d - root directory
	// * o - output format
	// * f - force pages
	private void separateArgs(String[] args) {
		for (int counter = 0; args != null && counter < args.length; counter++) {
			checkArg("-h", counter, args);
			checkArg("-a", counter, args);
			checkArg("-d", counter, args);
			checkArg("-f", counter, args);
			checkArgOutputFormat("-o", counter, args);
		}
	}

	private void checkArgOutputFormat(String option1, int index, String[] args) {
		if (args[index] != null && args[index].equals(option1) && index + 1 < args.length) {
			String clazz = args[index + 1];
			try {
				OutputFormat of = classExists(clazz);
				outputFormat = of;
			} catch (Exception e) {
				errors.add("Class '" + clazz + "' not found. Class must be supplied either as a fully qualified name or as a bare classname that can be found in the package "
						+ this.getClass().getPackage().getName() + ". Additionally, it must also implement the correct interface (" + OutputFormat.class.getName() + ")");
			}
		}
	}

	private OutputFormat classExists(String clazzName) throws Exception {
		String theRealClazz = clazzName;
		try {
			return (OutputFormat) Class.forName(clazzName).newInstance();
		} catch (Exception e) {
			try {
				theRealClazz = this.getClass().getPackage().getName() + "." + clazzName;
				return (OutputFormat) Class.forName(theRealClazz).newInstance();
			} catch (Exception e1) {
				throw e1;
			}
		}
	}

	private void checkArg(String option1, int index, String[] args) {
		if (args[index] != null && args[index].equals(option1) && index + 1 < args.length) {
			argMap.put(option1, args[index + 1]);
		}
	}

	public String getHost() {
		return argMap.get("-h");
	}

	public String getAssetTypes() {
		return argMap.get("-a");
	}

	public boolean getForcePageInclusion() {
		return "true".equalsIgnoreCase(argMap.get("-f"));
	}

	public String getRootDirectory() {
		return argMap.get("-d");
	}

	public OutputFormat getOutputFormat() {
		return outputFormat;
	}

	public List<String> getErrors() {
		return errors;
	}
}
